package com.slz3.business.module.systemManagement.sysUser.service;

import com.slz3.business.frame.enums.ValidFlag;
import com.slz3.business.frame.module.DomainEntity;
import com.slz3.business.frame.module.Repositorys;
import com.slz3.business.frame.module.Services;
import com.slz3.business.frame.steward.PageableSteward;
import com.slz3.business.module.systemManagement.sysOrganize.domain.SysOrganize;
import com.slz3.business.module.systemManagement.sysRoleUser.domain.SysRoleUser;
import com.slz3.business.module.systemManagement.sysUser.domain.SysUser;
import com.slz3.business.module.systemManagement.sysUser.domain.SysUserFactory;
import com.slz3.business.module.systemManagement.sysUser.steward.SysUserSpecification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {

    @Override
    public SysUser save(SysUser sysUser) {
        return Repositorys.sysUser.save(SysUserFactory.initBaseFields(sysUser));
    }

    @Override
    public Page<SysUser> page(MultiValueMap<String, String> params) {
        Page<SysUser> sysUserPage = Repositorys.sysUser.findAll(
                SysUserSpecification.findJoin(params), PageableSteward.extract(params)
        );
        Map<UUID, SysOrganize> collect = Repositorys.sysOrganize.findAllById(
                sysUserPage.stream().map(SysUser::getOrganizeUuid).filter(Objects::nonNull).collect(Collectors.toList())
        ).stream().collect(Collectors.toMap(SysOrganize::getUuid, Function.identity()));
        sysUserPage.stream().forEach(item -> item.setSysOrganize(collect.get(item.getOrganizeUuid())));
        return sysUserPage;
    }

    @Override
    public SysUser modify(SysUser sysUserNew) {
        return Repositorys.sysUser.saveAndFlush(SysUserFactory.initBaseFields(sysUserNew));
    }

    @Override
    public Optional<SysUser> single(UUID uuid) {
        Optional<SysUser> byId = Repositorys.sysUser.findById(uuid);
        byId.ifPresent(item -> {
            SysRoleUser sysRoleUser = new SysRoleUser();
            sysRoleUser.setUserUuid(item.getUuid());
            ExampleMatcher matcher = ExampleMatcher.matching()
                    .withMatcher("userUuid", ExampleMatcher.GenericPropertyMatchers.exact());
            List<SysRoleUser> allSysRoleUser = Repositorys.sysRoleUser.findAll(Example.of(sysRoleUser, matcher));
            item.setRoleUuids(allSysRoleUser.stream().map(roleUser -> roleUser.getRoleUuid()).collect(Collectors.toList()));
        });
        return byId;
    }

    @Override
    public List<SysUser> findAllByUuids(Iterable<UUID> uuids) {
        return Repositorys.sysUser.findAllById(uuids);
    }

    @Override
    public List<SysUser> delete(List<SysUser> sysUserList) {
        sysUserList.stream().forEach(item -> {
            item.setValidFlag(ValidFlag.DEL);
            SysUserFactory.initBaseFields(item);
        });
        return Services.sysUserTransactional.batchModify(sysUserList);
    }

    @Override
    public List<SysUser> findAll(SysUser param) {
        param.setValidFlag(ValidFlag.VALID);
        return Repositorys.sysUser.findAll(Example.of(param));
    }
}
